From: Jasper St. Pierre Date: Wed, 22 May 2013 18:46:47 +0000 (-0400) Subject: status: Rebrand the user menu as the system menu X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~3894 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=ca861d8ff9c93dad198e55e8d9afcaf04cee93a5;p=gnome-shell.git status: Rebrand the user menu as the system menu As the user menu no longer really shows anything about the user, and just power menu and settings, it's not really deserving of the "user menu" name, so rename it to the ever-blandly-named "system menu". This is a part of the new system status design, see https://wiki.gnome.org/GnomeShell/Design/Guidelines/SystemStatus/ for design details. https://bugzilla.gnome.org/show_bug.cgi?id=704368 --- diff --git a/js/Makefile.am b/js/Makefile.am index 4216df8de..556240fa2 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -95,10 +95,10 @@ nobase_dist_js_DATA = \ ui/status/power.js \ ui/status/volume.js \ ui/status/bluetooth.js \ + ui/status/system.js \ ui/switcherPopup.js \ ui/tweener.js \ ui/unlockDialog.js \ - ui/userMenu.js \ ui/userWidget.js \ ui/viewSelector.js \ ui/wanda.js \ diff --git a/js/ui/panel.js b/js/ui/panel.js index 795775f3d..1eca2b352 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -857,7 +857,7 @@ const PANEL_ITEM_IMPLEMENTATIONS = { 'lockScreen': imports.ui.status.lockScreenMenu.Indicator, 'keyboard': imports.ui.status.keyboard.InputSourceIndicator, 'powerMenu': imports.gdm.powerMenu.PowerMenuButton, - 'userMenu': imports.ui.userMenu.UserMenuButton + 'system': imports.ui.status.system.Indicator, }; if (Config.HAVE_BLUETOOTH) diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js index 4c849abfb..035739cca 100644 --- a/js/ui/sessionMode.js +++ b/js/ui/sessionMode.js @@ -60,7 +60,7 @@ const _modes = { unlockDialog: undefined, components: ['polkitAgent', 'telepathyClient'], panel: { - left: ['userMenu'], + left: [], center: [], right: ['lockScreen'] }, @@ -72,7 +72,7 @@ const _modes = { unlockDialog: undefined, components: ['polkitAgent', 'telepathyClient'], panel: { - left: ['userMenu'], + left: [], center: [], right: ['a11y', 'keyboard', 'lockScreen'] }, @@ -97,7 +97,7 @@ const _modes = { left: ['activities', 'appMenu'], center: ['dateMenu'], right: ['a11y', 'keyboard', 'volume', 'bluetooth', - 'network', 'battery', 'userMenu'] + 'network', 'battery', 'system'] } } }; diff --git a/js/ui/status/system.js b/js/ui/status/system.js new file mode 100644 index 000000000..6a5e43df3 --- /dev/null +++ b/js/ui/status/system.js @@ -0,0 +1,357 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +const AccountsService = imports.gi.AccountsService; +const Gdm = imports.gi.Gdm; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; +const Lang = imports.lang; +const St = imports.gi.St; +const Clutter = imports.gi.Clutter; + +const BoxPointer = imports.ui.boxpointer; +const GnomeSession = imports.misc.gnomeSession; +const LoginManager = imports.misc.loginManager; +const Main = imports.ui.main; +const ModalDialog = imports.ui.modalDialog; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; +const Util = imports.misc.util; +const UserWidget = imports.ui.userWidget; + +const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown'; +const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver'; +const PRIVACY_SCHEMA = 'org.gnome.desktop.privacy' +const DISABLE_USER_SWITCH_KEY = 'disable-user-switching'; +const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen'; +const DISABLE_LOG_OUT_KEY = 'disable-log-out'; +const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out'; + +const MAX_USERS_IN_SESSION_DIALOG = 5; + +const SystemdLoginSessionIface = + + + + + +; + +const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface); + +const Indicator = new Lang.Class({ + Name: 'SystemIndicator', + Extends: PanelMenu.SystemStatusButton, + + _init: function() { + this.parent('system-shutdown-symbolic', _("System")); + + this._screenSaverSettings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); + this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA }); + this._privacySettings = new Gio.Settings({ schema: PRIVACY_SCHEMA }); + + this._session = new GnomeSession.SessionManager(); + this._haveShutdown = true; + this._haveSuspend = true; + + this._createSubMenu(); + + this._loginManager = LoginManager.getLoginManager(); + this._userManager = AccountsService.UserManager.get_default(); + this._user = this._userManager.get_user(GLib.get_user_name()); + this._userManager.connect('notify::is-loaded', + Lang.bind(this, this._updateMultiUser)); + this._userManager.connect('notify::has-multiple-users', + Lang.bind(this, this._updateMultiUser)); + this._userManager.connect('user-added', + Lang.bind(this, this._updateMultiUser)); + this._userManager.connect('user-removed', + Lang.bind(this, this._updateMultiUser)); + this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY, + Lang.bind(this, this._updateSwitchUser)); + this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, + Lang.bind(this, this._updateLogout)); + this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY, + Lang.bind(this, this._updateLockScreen)); + global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY, + Lang.bind(this, this._updateLogout)); + this._updateSwitchUser(); + this._updateLogout(); + this._updateLockScreen(); + + this._updatesFile = Gio.File.new_for_path('/var/lib/PackageKit/prepared-update'); + this._updatesMonitor = this._updatesFile.monitor(Gio.FileMonitorFlags.NONE, null); + this._updatesMonitor.connect('changed', Lang.bind(this, this._updateInstallUpdates)); + + // Whether shutdown is available or not depends on both lockdown + // settings (disable-log-out) and Polkit policy - the latter doesn't + // notify, so we update the menu item each time the menu opens or + // the lockdown setting changes, which should be close enough. + this.menu.connect('open-state-changed', Lang.bind(this, + function(menu, open) { + if (!open) + return; + + this._updateHaveShutdown(); + this._updateHaveSuspend(); + })); + this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, + Lang.bind(this, this._updateHaveShutdown)); + + Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); + this._sessionUpdated(); + }, + + _sessionUpdated: function() { + this.actor.visible = !Main.sessionMode.isGreeter; + this.setSensitive(!Main.sessionMode.isLocked); + }, + + _updateMultiUser: function() { + this._updateSwitchUser(); + this._updateLogout(); + }, + + _updateSwitchUser: function() { + let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY); + let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users; + + this._loginScreenItem.actor.visible = allowSwitch && multiUser; + }, + + _updateLogout: function() { + let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY); + let alwaysShow = global.settings.get_boolean(ALWAYS_SHOW_LOG_OUT_KEY); + let systemAccount = this._user.system_account; + let localAccount = this._user.local_account; + let multiUser = this._userManager.has_multiple_users; + let multiSession = Gdm.get_session_ids().length > 1; + + this._logoutItem.actor.visible = allowLogout && (alwaysShow || multiUser || multiSession || systemAccount || !localAccount); + }, + + _updateLockScreen: function() { + let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY); + this._lockScreenItem.actor.visible = allowLockScreen && LoginManager.canLock(); + }, + + _updateInstallUpdates: function() { + let haveUpdates = this._updatesFile.query_exists(null); + this._installUpdatesItem.actor.visible = haveUpdates && this._haveShutdown; + }, + + _updateHaveShutdown: function() { + this._session.CanShutdownRemote(Lang.bind(this, + function(result, error) { + if (!error) { + this._haveShutdown = result[0]; + this._updateInstallUpdates(); + this._updateSuspendOrPowerOff(); + } + })); + }, + + _updateHaveSuspend: function() { + this._loginManager.canSuspend(Lang.bind(this, + function(result) { + this._haveSuspend = result; + this._updateSuspendOrPowerOff(); + })); + }, + + _updateSuspendOrPowerOff: function() { + if (!this._suspendOrPowerOffItem) + return; + + this._suspendOrPowerOffItem.actor.visible = this._haveShutdown || this._haveSuspend; + + // If we can't power off show Suspend instead + // and disable the alt key + if (!this._haveShutdown) { + this._suspendOrPowerOffItem.updateText(_("Suspend"), null); + } else if (!this._haveSuspend) { + this._suspendOrPowerOffItem.updateText(_("Power Off"), null); + } else { + this._suspendOrPowerOffItem.updateText(_("Power Off"), _("Suspend")); + } + }, + + _createSubMenu: function() { + let item; + + this.menu.addSettingsAction(_("Settings"), 'gnome-control-center.desktop'); + + item = new PopupMenu.PopupSeparatorMenuItem(); + this.menu.addMenuItem(item); + + item = new PopupMenu.PopupMenuItem(_("Switch User")); + item.connect('activate', Lang.bind(this, this._onLoginScreenActivate)); + this.menu.addMenuItem(item); + this._loginScreenItem = item; + + item = new PopupMenu.PopupMenuItem(_("Log Out")); + item.connect('activate', Lang.bind(this, this._onQuitSessionActivate)); + this.menu.addMenuItem(item); + this._logoutItem = item; + + item = new PopupMenu.PopupMenuItem(_("Lock")); + item.connect('activate', Lang.bind(this, this._onLockScreenActivate)); + this.menu.addMenuItem(item); + this._lockScreenItem = item; + + item = new PopupMenu.PopupSeparatorMenuItem(); + this.menu.addMenuItem(item); + + item = new PopupMenu.PopupAlternatingMenuItem(_("Power Off"), + _("Suspend")); + this.menu.addMenuItem(item); + item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate)); + this._suspendOrPowerOffItem = item; + this._updateSuspendOrPowerOff(); + + item = new PopupMenu.PopupMenuItem(_("Install Updates & Restart")); + item.connect('activate', Lang.bind(this, this._onInstallUpdatesActivate)); + this.menu.addMenuItem(item); + this._installUpdatesItem = item; + }, + + _onLockScreenActivate: function() { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + Main.overview.hide(); + Main.screenShield.lock(true); + }, + + _onLoginScreenActivate: function() { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + Main.overview.hide(); + if (Main.screenShield) + Main.screenShield.lock(false); + Gdm.goto_login_session_sync(null); + }, + + _onQuitSessionActivate: function() { + Main.overview.hide(); + this._session.LogoutRemote(0); + }, + + _onInstallUpdatesActivate: function() { + Main.overview.hide(); + Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']); + + this._session.RebootRemote(); + }, + + _openSessionWarnDialog: function(sessions) { + let dialog = new ModalDialog.ModalDialog(); + let subjectLabel = new St.Label({ style_class: 'end-session-dialog-subject', + text: _("Other users are logged in.") }); + dialog.contentLayout.add(subjectLabel, { y_fill: true, + y_align: St.Align.START }); + + let descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description'}); + descriptionLabel.set_text(_("Shutting down might cause them to lose unsaved work.")); + descriptionLabel.clutter_text.line_wrap = true; + dialog.contentLayout.add(descriptionLabel, { x_fill: true, + y_fill: true, + y_align: St.Align.START }); + + let scrollView = new St.ScrollView({ style_class: 'end-session-dialog-app-list' }); + scrollView.add_style_class_name('vfade'); + scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); + dialog.contentLayout.add(scrollView, { x_fill: true, y_fill: true }); + + let userList = new St.BoxLayout({ vertical: true }); + scrollView.add_actor(userList); + + for (let i = 0; i < sessions.length; i++) { + let session = sessions[i]; + let userEntry = new St.BoxLayout({ style_class: 'login-dialog-user-list-item', + vertical: false }); + let avatar = new UserWidget.Avatar(session.user); + avatar.update(); + userEntry.add(avatar.actor); + + let userLabelText = "";; + let userName = session.user.get_real_name() ? + session.user.get_real_name() : session.username; + + if (session.info.remote) + /* Translators: Remote here refers to a remote session, like a ssh login */ + userLabelText = _("%s (remote)").format(userName); + else if (session.info.type == "tty") + /* Translators: Console here refers to a tty like a VT console */ + userLabelText = _("%s (console)").format(userName); + else + userLabelText = userName; + + let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box', + vertical: true }); + textLayout.add(new St.Label({ text: userLabelText }), + { y_fill: false, + y_align: St.Align.MIDDLE, + expand: true }); + userEntry.add(textLayout, { expand: true }); + userList.add(userEntry, { x_fill: true }); + } + + let cancelButton = { label: _("Cancel"), + action: function() { dialog.close(); }, + key: Clutter.Escape }; + + let powerOffButton = { label: _("Power Off"), action: Lang.bind(this, function() { + dialog.close(); + this._session.ShutdownRemote(); + }), default: true }; + + dialog.setButtons([cancelButton, powerOffButton]); + + dialog.open(); + }, + + _onSuspendOrPowerOffActivate: function() { + Main.overview.hide(); + + if (this._haveShutdown && + this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) { + this._loginManager.listSessions(Lang.bind(this, + function(result) { + let sessions = []; + let n = 0; + for (let i = 0; i < result.length; i++) { + let[id, uid, userName, seat, sessionPath] = result[i]; + let proxy = new SystemdLoginSession(Gio.DBus.system, + 'org.freedesktop.login1', + sessionPath); + + if (proxy.Class != 'user') + continue; + + if (proxy.State == 'closing') + continue; + + if (proxy.Id == GLib.getenv('XDG_SESSION_ID')) + continue; + + sessions.push({ user: this._userManager.get_user(userName), + username: userName, + info: { type: proxy.Type, + remote: proxy.Remote } + }); + + // limit the number of entries + n++; + if (n == MAX_USERS_IN_SESSION_DIALOG) + break; + } + + if (n != 0) + this._openSessionWarnDialog(sessions); + else + this._session.ShutdownRemote(); + })); + } else { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + this._loginManager.suspend(); + } + } +}); diff --git a/js/ui/userMenu.js b/js/ui/userMenu.js deleted file mode 100644 index 66173d5ef..000000000 --- a/js/ui/userMenu.js +++ /dev/null @@ -1,357 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const AccountsService = imports.gi.AccountsService; -const Gdm = imports.gi.Gdm; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; -const St = imports.gi.St; -const Clutter = imports.gi.Clutter; - -const BoxPointer = imports.ui.boxpointer; -const GnomeSession = imports.misc.gnomeSession; -const LoginManager = imports.misc.loginManager; -const Main = imports.ui.main; -const ModalDialog = imports.ui.modalDialog; -const PanelMenu = imports.ui.panelMenu; -const PopupMenu = imports.ui.popupMenu; -const Util = imports.misc.util; -const UserWidget = imports.ui.userWidget; - -const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown'; -const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver'; -const PRIVACY_SCHEMA = 'org.gnome.desktop.privacy' -const DISABLE_USER_SWITCH_KEY = 'disable-user-switching'; -const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen'; -const DISABLE_LOG_OUT_KEY = 'disable-log-out'; -const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out'; - -const MAX_USERS_IN_SESSION_DIALOG = 5; - -const SystemdLoginSessionIface = - - - - - -; - -const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface); - -const UserMenuButton = new Lang.Class({ - Name: 'UserMenuButton', - Extends: PanelMenu.SystemStatusButton, - - _init: function() { - this.parent('user-available-symbolic', _("User Menu")); - - this._screenSaverSettings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); - this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA }); - this._privacySettings = new Gio.Settings({ schema: PRIVACY_SCHEMA }); - - this._session = new GnomeSession.SessionManager(); - this._haveShutdown = true; - this._haveSuspend = true; - - this._createSubMenu(); - - this._loginManager = LoginManager.getLoginManager(); - this._userManager = AccountsService.UserManager.get_default(); - this._user = this._userManager.get_user(GLib.get_user_name()); - this._userManager.connect('notify::is-loaded', - Lang.bind(this, this._updateMultiUser)); - this._userManager.connect('notify::has-multiple-users', - Lang.bind(this, this._updateMultiUser)); - this._userManager.connect('user-added', - Lang.bind(this, this._updateMultiUser)); - this._userManager.connect('user-removed', - Lang.bind(this, this._updateMultiUser)); - this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY, - Lang.bind(this, this._updateSwitchUser)); - this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, - Lang.bind(this, this._updateLogout)); - this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY, - Lang.bind(this, this._updateLockScreen)); - global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY, - Lang.bind(this, this._updateLogout)); - this._updateSwitchUser(); - this._updateLogout(); - this._updateLockScreen(); - - this._updatesFile = Gio.File.new_for_path('/var/lib/PackageKit/prepared-update'); - this._updatesMonitor = this._updatesFile.monitor(Gio.FileMonitorFlags.NONE, null); - this._updatesMonitor.connect('changed', Lang.bind(this, this._updateInstallUpdates)); - - // Whether shutdown is available or not depends on both lockdown - // settings (disable-log-out) and Polkit policy - the latter doesn't - // notify, so we update the menu item each time the menu opens or - // the lockdown setting changes, which should be close enough. - this.menu.connect('open-state-changed', Lang.bind(this, - function(menu, open) { - if (!open) - return; - - this._updateHaveShutdown(); - this._updateHaveSuspend(); - })); - this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, - Lang.bind(this, this._updateHaveShutdown)); - - Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); - this._sessionUpdated(); - }, - - _sessionUpdated: function() { - this.actor.visible = !Main.sessionMode.isGreeter; - this.setSensitive(!Main.sessionMode.isLocked); - }, - - _updateMultiUser: function() { - this._updateSwitchUser(); - this._updateLogout(); - }, - - _updateSwitchUser: function() { - let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY); - let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users; - - this._loginScreenItem.actor.visible = allowSwitch && multiUser; - }, - - _updateLogout: function() { - let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY); - let alwaysShow = global.settings.get_boolean(ALWAYS_SHOW_LOG_OUT_KEY); - let systemAccount = this._user.system_account; - let localAccount = this._user.local_account; - let multiUser = this._userManager.has_multiple_users; - let multiSession = Gdm.get_session_ids().length > 1; - - this._logoutItem.actor.visible = allowLogout && (alwaysShow || multiUser || multiSession || systemAccount || !localAccount); - }, - - _updateLockScreen: function() { - let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY); - this._lockScreenItem.actor.visible = allowLockScreen && LoginManager.canLock(); - }, - - _updateInstallUpdates: function() { - let haveUpdates = this._updatesFile.query_exists(null); - this._installUpdatesItem.actor.visible = haveUpdates && this._haveShutdown; - }, - - _updateHaveShutdown: function() { - this._session.CanShutdownRemote(Lang.bind(this, - function(result, error) { - if (!error) { - this._haveShutdown = result[0]; - this._updateInstallUpdates(); - this._updateSuspendOrPowerOff(); - } - })); - }, - - _updateHaveSuspend: function() { - this._loginManager.canSuspend(Lang.bind(this, - function(result) { - this._haveSuspend = result; - this._updateSuspendOrPowerOff(); - })); - }, - - _updateSuspendOrPowerOff: function() { - if (!this._suspendOrPowerOffItem) - return; - - this._suspendOrPowerOffItem.actor.visible = this._haveShutdown || this._haveSuspend; - - // If we can't power off show Suspend instead - // and disable the alt key - if (!this._haveShutdown) { - this._suspendOrPowerOffItem.updateText(_("Suspend"), null); - } else if (!this._haveSuspend) { - this._suspendOrPowerOffItem.updateText(_("Power Off"), null); - } else { - this._suspendOrPowerOffItem.updateText(_("Power Off"), _("Suspend")); - } - }, - - _createSubMenu: function() { - let item; - - this.menu.addSettingsAction(_("Settings"), 'gnome-control-center.desktop'); - - item = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(item); - - item = new PopupMenu.PopupMenuItem(_("Switch User")); - item.connect('activate', Lang.bind(this, this._onLoginScreenActivate)); - this.menu.addMenuItem(item); - this._loginScreenItem = item; - - item = new PopupMenu.PopupMenuItem(_("Log Out")); - item.connect('activate', Lang.bind(this, this._onQuitSessionActivate)); - this.menu.addMenuItem(item); - this._logoutItem = item; - - item = new PopupMenu.PopupMenuItem(_("Lock")); - item.connect('activate', Lang.bind(this, this._onLockScreenActivate)); - this.menu.addMenuItem(item); - this._lockScreenItem = item; - - item = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(item); - - item = new PopupMenu.PopupAlternatingMenuItem(_("Power Off"), - _("Suspend")); - this.menu.addMenuItem(item); - item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate)); - this._suspendOrPowerOffItem = item; - this._updateSuspendOrPowerOff(); - - item = new PopupMenu.PopupMenuItem(_("Install Updates & Restart")); - item.connect('activate', Lang.bind(this, this._onInstallUpdatesActivate)); - this.menu.addMenuItem(item); - this._installUpdatesItem = item; - }, - - _onLockScreenActivate: function() { - this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); - Main.overview.hide(); - Main.screenShield.lock(true); - }, - - _onLoginScreenActivate: function() { - this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); - Main.overview.hide(); - if (Main.screenShield) - Main.screenShield.lock(false); - Gdm.goto_login_session_sync(null); - }, - - _onQuitSessionActivate: function() { - Main.overview.hide(); - this._session.LogoutRemote(0); - }, - - _onInstallUpdatesActivate: function() { - Main.overview.hide(); - Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']); - - this._session.RebootRemote(); - }, - - _openSessionWarnDialog: function(sessions) { - let dialog = new ModalDialog.ModalDialog(); - let subjectLabel = new St.Label({ style_class: 'end-session-dialog-subject', - text: _("Other users are logged in.") }); - dialog.contentLayout.add(subjectLabel, { y_fill: true, - y_align: St.Align.START }); - - let descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description'}); - descriptionLabel.set_text(_("Shutting down might cause them to lose unsaved work.")); - descriptionLabel.clutter_text.line_wrap = true; - dialog.contentLayout.add(descriptionLabel, { x_fill: true, - y_fill: true, - y_align: St.Align.START }); - - let scrollView = new St.ScrollView({ style_class: 'end-session-dialog-app-list' }); - scrollView.add_style_class_name('vfade'); - scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); - dialog.contentLayout.add(scrollView, { x_fill: true, y_fill: true }); - - let userList = new St.BoxLayout({ vertical: true }); - scrollView.add_actor(userList); - - for (let i = 0; i < sessions.length; i++) { - let session = sessions[i]; - let userEntry = new St.BoxLayout({ style_class: 'login-dialog-user-list-item', - vertical: false }); - let avatar = new UserWidget.Avatar(session.user); - avatar.update(); - userEntry.add(avatar.actor); - - let userLabelText = "";; - let userName = session.user.get_real_name() ? - session.user.get_real_name() : session.username; - - if (session.info.remote) - /* Translators: Remote here refers to a remote session, like a ssh login */ - userLabelText = _("%s (remote)").format(userName); - else if (session.info.type == "tty") - /* Translators: Console here refers to a tty like a VT console */ - userLabelText = _("%s (console)").format(userName); - else - userLabelText = userName; - - let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box', - vertical: true }); - textLayout.add(new St.Label({ text: userLabelText }), - { y_fill: false, - y_align: St.Align.MIDDLE, - expand: true }); - userEntry.add(textLayout, { expand: true }); - userList.add(userEntry, { x_fill: true }); - } - - let cancelButton = { label: _("Cancel"), - action: function() { dialog.close(); }, - key: Clutter.Escape }; - - let powerOffButton = { label: _("Power Off"), action: Lang.bind(this, function() { - dialog.close(); - this._session.ShutdownRemote(); - }), default: true }; - - dialog.setButtons([cancelButton, powerOffButton]); - - dialog.open(); - }, - - _onSuspendOrPowerOffActivate: function() { - Main.overview.hide(); - - if (this._haveShutdown && - this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) { - this._loginManager.listSessions(Lang.bind(this, - function(result) { - let sessions = []; - let n = 0; - for (let i = 0; i < result.length; i++) { - let[id, uid, userName, seat, sessionPath] = result[i]; - let proxy = new SystemdLoginSession(Gio.DBus.system, - 'org.freedesktop.login1', - sessionPath); - - if (proxy.Class != 'user') - continue; - - if (proxy.State == 'closing') - continue; - - if (proxy.Id == GLib.getenv('XDG_SESSION_ID')) - continue; - - sessions.push({ user: this._userManager.get_user(userName), - username: userName, - info: { type: proxy.Type, - remote: proxy.Remote } - }); - - // limit the number of entries - n++; - if (n == MAX_USERS_IN_SESSION_DIALOG) - break; - } - - if (n != 0) - this._openSessionWarnDialog(sessions); - else - this._session.ShutdownRemote(); - })); - } else { - this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); - this._loginManager.suspend(); - } - } -});